Skip to content

feat(postgresql): message-store reset clears the Postgres transport queue tables - #3

Draft
uniquelau wants to merge 1 commit into
mainfrom
feat/clear-transport-queue-tables
Draft

feat(postgresql): message-store reset clears the Postgres transport queue tables#3
uniquelau wants to merge 1 commit into
mainfrom
feat/clear-transport-queue-tables

Conversation

@uniquelau

Copy link
Copy Markdown
Owner

Review copy on our fork — please review before I open this against JasperFx/wolverine.

Problem

ClearAllAsync() / the message-store reset truncates incoming/outgoing/dead-letter/node/listener tables but not the Postgres transport queue tables. Integration tests over the Postgres queue transport therefore carry queue rows between runs and need a bespoke reset.

Change (transactional, additive, Postgres-scoped)

  • MessageDatabase.Admin.cs — new protected virtual truncateAdditionalTablesAsync(DbTransaction, CancellationToken) hook (default no-op), invoked inside the existing reset transaction just before commit — so any extra clears run atomically with the envelope truncation.
  • PostgresqlMessageStore.cs — override that clears only the transport's QueueTable / ScheduledMessageTable (matched by type from the registered _otherTables), reusing the transport's own delete from {table} pattern.
  • Test reset_clears_transport_queue_tables — enqueues one immediate + one scheduled message, calls ClearAllAsync(), asserts both counts drop to 0. Negative control confirmed: with the hook call disabled the test fails; enabled it passes.

Why not a base-class loop: SqlServer registers a RateLimitTable through the same AddTable path, so a blanket "truncate every registered table" would wrongly clear it. This keeps the behaviour Postgres-scoped via the virtual hook — SqlServer and other providers keep the no-op default (their build is confirmed green, 0 warnings).

No public API added. 43 lines across two source files.

One design point for your call before upstream

The Postgres override identifies the transport tables by filtering _otherTables for the internal QueueTable/ScheduledMessageTable types — zero transport changes, no new public surface, but it couples the store to the transport's table classes (same assembly, so acceptable). The alternative is an explicit "register this table for reset-clearing" call from the transport — more decoupled, but adds an API and a call site. I took the minimal no-new-API path; easy to flip if the maintainer prefers the explicit registration.

ClearAllAsync / RebuildAsync previously truncated only the envelope tables
(incoming/outgoing/dead-letter/node/listener), leaving the PostgreSQL queue
transport's queue and scheduled-message tables populated. Integration tests
over the Postgres queue transport therefore carried rows between runs.

Add a per-provider hook, truncateAdditionalTablesAsync(DbTransaction), invoked
inside the existing reset transaction so the whole reset stays atomic. The
PostgreSQL store overrides it to delete from the transport's own queue +
scheduled tables. Scoped to the transport's table types on purpose: AddTable is
a general registration path (SQL Server registers a rate-limit table through it
that a reset must keep), so a blanket base-class loop would be wrong. Default
behaviour for every other provider is unchanged. No public API added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@uniquelau
uniquelau force-pushed the feat/clear-transport-queue-tables branch from 84bbb5e to eac0c23 Compare July 20, 2026 08:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant